home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / ip / ppp / mac / macppp1.1.3-src.hqx / MacPPP1.1.3-src / pppcdev.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-09  |  43.8 KB  |  1,621 lines

  1. /*
  2.  *  pppcdev.c    -- The Control Panel for MacPPP
  3.  *
  4.  * Copyright (c) 1992-1993 Merit Network, Inc. and The Regents of the
  5.  *  University of Michigan.  Usage of this source code is restricted
  6.  *  to non-profit, non-commercial purposes.  The source is provided
  7.  *  "as-is", without warranty.
  8.  */
  9. #include "ppp.h"
  10. #include <GestaltEqu.h>
  11. #include <CommResources.h>
  12. #include <CRMSerialDevices.h>
  13. #include <Folders.h>
  14. #include <Menus.h>
  15. #include <ToolUtils.h>
  16.  
  17. /* Trap numbers */
  18. #define TN_UnknownOS        0xA09F
  19. #define TN_CommToolbox        0xA08B
  20.  
  21. /* Menus */
  22. #define BAUDMENU -4033
  23. #define PORTMENU -4034
  24. #define IDLEMENU -4035
  25. #define SERVERMENU -4036
  26. #define ECHOMENU -4037
  27.  
  28. /* ICONs */
  29. #define PPPUPICON -4033
  30. #define PPPDOWNICON -4034
  31.  
  32. /* Default preferences resources */
  33. #define DEFAULTPREF -4033
  34. #define DEFAULTLCP -4034
  35. #define DEFAULTIPCP -4035
  36. #define DEFAULTCNFGNAME -4036
  37.  
  38. /* STR# resources */
  39. #define STATUSSTRINGS -4033
  40. #define CANNEDPORTS -4034
  41.  
  42. /* status strings */
  43. #define ACCMMESS 1        /* invalid ACCM */
  44. #define MRUMESS 2        /* invalid MRU */
  45. #define IPMESS 3        /* invalid IP address */
  46. #define STRINGMESS 4    /* string too long */
  47. #define PREFSCMESS 5    /* Pref file create error */
  48. #define PREFSOMESS 6    /* Pref file open error */
  49. #define PREFSRMESS 7    /* Pref file read error */
  50. #define PREFSWMESS 8    /* Pref file write error */
  51. #define OLDPREFSMESS 9    /* there's an old version of the preferences file */
  52. #define CONFIGMESS 10    /* must be more than one config for deletion */
  53. #define NULLMESS 11        /* null length server name */
  54. #define SAMEMESS 12        /* name is the same as another server */
  55.  
  56. /* number for Preferences file name */
  57. #define PREFFILENAME -4033
  58. #define SYS6FOLDER -4034
  59.  
  60. /* Dialog numbers */
  61. #define SCRIPTDLOG -4033
  62. #define CONNECTDLOG -4034
  63. #define LCPDLOG -4035
  64. #define STATSDLOG -4036
  65. #define AUTHDLOG -4037
  66. #define IPCPDLOG -4038
  67. #define ASKDLOG -4039
  68.  
  69. /* Alerts */
  70. #define ERRALERT -4033
  71. #define OLDPREFSALERT -4034
  72.  
  73. /* cdev dialog items (add numitems to these) */
  74. #define OPENBTN 1
  75. #define SOFTCLOSEBTN 2
  76. #define HARDCLOSEBTN 3
  77. #define STATSBTN 4
  78. #define PTITLERECT 5
  79. #define PORTRECT 6
  80. #define    ITITLERECT 7
  81. #define IDLERECT 8
  82. #define ETITLERECT 9
  83. #define ECHORECT 10
  84. #define STITLERECT 11
  85. #define SERVERRECT 12
  86. #define CONFIGBTN 13
  87. #define TONE 14
  88. #define PULSE 15
  89. #define TERMCHECK 16
  90. #define HANGUPCHECK 17
  91. #define QUIETCHECK 18
  92. #define PPPICON 19
  93.  
  94. /* config dialog */
  95. #define SERVERNAME 3
  96. #define NEWSERVER 4
  97. #define DELETESERVER 5
  98. #define BTITLERECT 6
  99. #define BAUDRECT 7
  100. #define CTSCHECK 8
  101. #define PHONENUM 11
  102. #define MODEMINIT 12
  103. #define SCRIPTBTN 13
  104. #define AUTHBTN 14
  105. #define LCPBTN 15
  106. #define IPCPBTN 16
  107. #define CONNECTTIME 18
  108.  
  109. /* connect script dialog */
  110. #define COMMANDBTNS 3
  111. #define COMMANDS 19
  112. #define ADDRETURNS 28
  113. #define WAITTIME 37
  114.  
  115. /* auth fields */
  116. #define AUTHID 3
  117. #define AUTHPW 4
  118. #define AUTHRETRIES 9
  119. #define AUTHTIMEOUT 11
  120.  
  121. /* LCP options dialog items */
  122. #define LCPDEFAULT 3
  123. #define PFCBOXES 15
  124. #define ACFCBOXES 19
  125. #define AUTHENTBOXES 23
  126. #define MAGICBOXES 27
  127. #define    ACCMBOXES 33
  128. #define MRUBOXES 39
  129. #define LCPRETRIES 46
  130. #define LCPTIMEOUT 48
  131.  
  132. /* IPCP options dialog items */
  133. #define IPCPDEFAULT 3
  134. #define COMPRESSBOXES 8
  135. #define ADDRESSBOXES 12
  136. #define IPCPRETRIES 21
  137. #define IPCPTIMEOUT 23
  138.  
  139. /* stats boxes */
  140. #define UPDATEBTN 2
  141. #define    INOCTETS 13
  142. #define OUTOCTETS 14
  143. #define INPACKETS 15
  144. #define OUTPACKETS 16
  145. #define CHECKSEQERRS 17
  146. #define HEADERERRS 18
  147. #define HWOVERRUNS 19
  148. #define SWOVERRUNS 20
  149. #define FRAMINGERRS 21
  150. #define OUTOFBUFS 22
  151. #define PFCVALS 35
  152. #define ACFCVALS 37
  153. #define PAPVALS 39
  154. #define MAGICVALS 41
  155. #define ACCMVALS 43
  156. #define MRUVALS 45
  157. #define VJVALS 47
  158. #define VJSLOTS 55
  159. #define VJCID 59
  160. #define IPADDRVALS 49
  161.  
  162. struct mydlogrec {
  163.     DialogRecord    adlogrec;
  164.     char            *strptr;
  165. };
  166.  
  167. struct cdevstore {
  168.     struct popup {
  169.         MenuHandle    menuh;        /* Handle to popupmenu */
  170.         Rect        poprect;    /* rectangle to do popupmenu */
  171.         Rect        titlerect;    /* rectangle to invert */
  172.         } port, baud, idle, server, echo;
  173.     int    prefref;                /* file ref for PPP preferences */
  174.     struct lcpconfig deflcp;    /* default LCP settings */
  175.     struct ipcpconfig defipcp;    /* default IPCP settings */
  176.     struct ppp_pref prefdata;    /* Preferences data */
  177.     struct ppp_config prefcnfg;    /* current config settings */
  178.     };
  179.  
  180. void AppendStr(unsigned char *, unsigned char *);
  181. void MyNoteAlert(unsigned char);
  182. void updatecp(struct cdevstore *, DialogPtr, int);
  183. OSErr updateprefs(struct cdevstore *);
  184. OSErr readconfig(struct cdevstore *, int);
  185. void initconfigs(struct cdevstore *);
  186. void dostatsdlog(), doauthdlog(struct cdevstore *);
  187. void dolcpdlog(struct cdevstore *), doipcpdlog(struct cdevstore *);
  188. void doconfigdlog (struct cdevstore *), doscriptdlog(struct cdevstore *);
  189. long DoPopInt(struct popup *, unsigned int *);
  190. long DoPopUp(struct popup *, char *);
  191. void drawpopup(struct popup *, DialogPtr, char *);
  192. void drawpopint(struct popup *, DialogPtr, unsigned int);
  193. pascal    Boolean dumbfilter(DialogPtr, EventRecord *, int *);
  194. Boolean gettext(DialogPtr, int, char *);
  195. Boolean getbyte(DialogPtr, int, b_8 *);
  196. void dosetctlval(DialogPtr, int, int);
  197. void dosetilong(DialogPtr, int, b_32);
  198. void dosetitext(DialogPtr, int, char *);
  199. void dosethex(DialogPtr, int, b_32);
  200. void dosetipaddr(DialogPtr, int, b_32);
  201. void dosetcbox(DialogPtr, int, int);
  202. void getnegval(DialogPtr, int, int, int *);
  203. void setbuttons(DialogPtr, int);
  204.  
  205. pascal long pppcdev(int msg, int item, int numitems, int cpid, EventRecord *evt,
  206.                         struct cdevstore *p, DialogPtr dlogp)
  207. {
  208. LapInfo        *lap;
  209. Handle        itemH;
  210. Str63        workstr;
  211. int            type;
  212. long        rv;
  213. Rect        box;
  214. OSErr        onewresult, oresult;
  215.  
  216.     if ( msg == macDev )
  217.         return(1L);     /* this will work anywhere */
  218.     else if ( msg == initDev ) {
  219.         struct        cdevstore *tempcdev;
  220.         Handle        tempH;
  221.         int            i, rn, prefVol;
  222.         long        prefDir, count;
  223.         Boolean        commtoolbox, HaveFindFolder, HavePrefFolder;
  224.  
  225.         /* get some mem.  I suppose this should be Handle instead. */
  226.         tempcdev = (struct cdevstore *)NewPtr(sizeof(struct cdevstore));
  227.         if (tempcdev == 0L)
  228.             return (0L);
  229.         
  230.         if (commtoolbox = 
  231.             (NGetTrapAddress(TN_CommToolbox, OSTrap) != GetTrapAddress(TN_UnknownOS)))
  232.             InitCRM();
  233.         /* try to find our Preferences folder and open Prefs file */
  234.         HaveFindFolder = HavePrefFolder = false;
  235.         if ( Gestalt(gestaltFindFolderAttr, &rv) == noErr) {
  236.             if ( ( 1L << gestaltFindFolderPresent ) & rv ) {
  237.                 HaveFindFolder = true;
  238.                 if ( FindFolder(kOnSystemDisk,kPreferencesFolderType,
  239.                     kCreateFolder,&prefVol,&prefDir) == noErr)
  240.                     HavePrefFolder = true;
  241.             }
  242.         }
  243.         
  244.         workstr[0] = 0;
  245.         if (!HavePrefFolder) {
  246.             tempH = GetResource('STR ',SYS6FOLDER); /* system 6 folder */
  247.             AppendStr(workstr, *((char **) tempH));
  248.             ReleaseResource(tempH);
  249.         }
  250.         tempH = GetResource('STR ',PREFFILENAME); /* get pref file */
  251.         AppendStr(workstr, *((char **) tempH));
  252.         ReleaseResource(tempH);
  253.         
  254.         rn = -1;
  255.         if (HavePrefFolder) {
  256.             if ( (oresult = HOpen(prefVol,prefDir,workstr,fsRdWrPerm,&rn)) == fnfErr ) {
  257.                 HCreate(prefVol,prefDir,workstr,'Mppp','PREF');
  258.                 onewresult = HOpen(prefVol,prefDir,workstr,fsRdWrPerm,&rn);
  259.             }
  260.         /* if we don't have PrefFolder, just use System Folder */
  261.         } else {
  262.             GetVRefNum(SysMap, &prefVol);    /* get system Vol ref */
  263.             if ( (oresult = FSOpen(workstr,prefVol,&rn)) == fnfErr ) {
  264.                 Create(workstr,prefVol,'Mppp','PREF');
  265.                 onewresult = FSOpen(workstr,prefVol,&rn);
  266.             }
  267.         }
  268.         
  269.         tempH = GetResource('cnfg',DEFAULTLCP);
  270.         tempcdev->deflcp = **((struct lcpconfig **) tempH);
  271.         ReleaseResource(tempH);
  272.         tempH = GetResource('cnfg',DEFAULTIPCP);
  273.         tempcdev->defipcp = **((struct ipcpconfig **) tempH);
  274.         ReleaseResource(tempH);
  275.  
  276.         tempcdev->prefref = rn;
  277.  
  278.         if ( oresult == fnfErr ) {
  279.             if (onewresult != noErr) {
  280.                 MyNoteAlert(PREFSCMESS);
  281.                 DisposePtr(tempcdev);
  282.                 return (-1);
  283.             }
  284. new_configs:
  285.             tempH = GetResource('cnfg',DEFAULTPREF);
  286.             tempcdev->prefdata = **((struct ppp_pref **) tempH);    /* copy struct */
  287.             ReleaseResource(tempH);
  288.             initconfigs(tempcdev);
  289.             tempH = GetResource('cnfg',DEFAULTCNFGNAME);
  290.             AppendStr(tempcdev->prefcnfg.config_name, *((unsigned char **) tempH));
  291.             ReleaseResource(tempH);
  292.             updateprefs(tempcdev);
  293.         } else if (rn != -1 && oresult == noErr) {
  294.             count = sizeof (struct ppp_pref);
  295.             oresult = FSRead(rn, &count, &(tempcdev->prefdata));
  296.             if (tempcdev->prefdata.version < PREF_VERSION) {
  297.                 if (NoteAlert(OLDPREFSALERT,nil) == OK)
  298.                     goto new_configs;
  299.                 else {
  300.                     FSClose(rn);
  301.                     DisposePtr(tempcdev);
  302.                     return (-1);
  303.                 }
  304.             }
  305.         } else {
  306.             MyNoteAlert(PREFSOMESS);
  307.             DisposePtr(tempcdev);
  308.             return (-1);
  309.         }
  310.  
  311.                 /* get the pop-up menus */
  312.  
  313.         tempcdev->server.menuh = GetMenu(SERVERMENU);
  314.         for (i=0 ; i < tempcdev->prefdata.max_config; i++ ) {
  315.             if ( readconfig(tempcdev, i) != noErr) {
  316.                 ReleaseResource(tempcdev->server.menuh);
  317.                 FSClose(rn);
  318.                 DisposePtr(tempcdev);
  319.                 return (-1);
  320.             }
  321.             AppendMenu(tempcdev->server.menuh, "\p ");
  322.             SetItem(tempcdev->server.menuh, i + 1, 
  323.                         tempcdev->prefcnfg.config_name);
  324.         }
  325.         readconfig(tempcdev, tempcdev->prefdata.active_config);
  326.         tempcdev->baud.menuh = GetMenu(BAUDMENU);
  327.         tempcdev->idle.menuh = GetMenu(IDLEMENU);
  328.         tempcdev->port.menuh = GetMenu(PORTMENU);
  329.         tempcdev->echo.menuh = GetMenu(ECHOMENU);
  330.         if (commtoolbox) {
  331.             CRMRec *crmrecptr, acrmrec;
  332.             CRMSerialRecord *serrec;
  333.             long old = 0;
  334.             int index = 1;
  335.  
  336.             acrmrec.qType = crmType;
  337.             while (true) {
  338.                 acrmrec.crmDeviceType = crmSerialDevice;
  339.                 acrmrec.crmDeviceID = old;
  340.                 if (!(crmrecptr = (CRMRec *)CRMSearch((QElemPtr)(&acrmrec))))
  341.                     break;
  342.                 serrec = (CRMSerialRecord *)crmrecptr->crmAttributes;
  343.                 /* must do a set item because of special characters */
  344.                 AppendMenu(tempcdev->port.menuh, "\p ");
  345.                 SetItem(tempcdev->port.menuh, index, *(serrec->name));
  346.                 old = crmrecptr->crmDeviceID;
  347.                 ++index;
  348.             }
  349.         } else {
  350.             AddResMenu(tempcdev->port.menuh, 'Port');
  351.         }
  352.         /* get port rects */
  353.         GetDItem(dlogp, PORTRECT + numitems, &type, &itemH, &(tempcdev->port.poprect));
  354.         GetDItem(dlogp, PTITLERECT + numitems, &type, &itemH, &(tempcdev->port.titlerect));
  355.         /* get idle timeout rects */
  356.         GetDItem(dlogp, IDLERECT + numitems, &type, &itemH, &(tempcdev->idle.poprect));
  357.         GetDItem(dlogp, ITITLERECT + numitems, &type, &itemH, &(tempcdev->idle.titlerect));
  358.         /* get server rects */
  359.         GetDItem(dlogp, SERVERRECT + numitems, &type, &itemH, &(tempcdev->server.poprect));
  360.         GetDItem(dlogp, STITLERECT + numitems, &type, &itemH, &(tempcdev->server.titlerect));
  361.         /* get LCP echo interval rects */
  362.         GetDItem(dlogp, ECHORECT + numitems, &type, &itemH, &(tempcdev->echo.poprect));
  363.         GetDItem(dlogp, ETITLERECT + numitems, &type, &itemH, &(tempcdev->echo.titlerect));
  364.  
  365.         /* pulse/touchtone dialing */
  366.         i = tempcdev->prefdata.use_pulse ? PULSE : TONE;
  367.         dosetctlval(dlogp, i + numitems, 1);
  368.         /* term window checkbox */
  369.         if (tempcdev->prefdata.use_term)
  370.             dosetctlval(dlogp, TERMCHECK + numitems, 1);
  371.         /* hangup checkbox */
  372.         if (tempcdev->prefdata.hangup)
  373.             dosetctlval(dlogp, HANGUPCHECK + numitems, 1);
  374.         /* quiet checkbox */
  375.         if (tempcdev->prefdata.quiet)
  376.             dosetctlval(dlogp, QUIETCHECK + numitems, 1);
  377.         setbuttons(dlogp, numitems);
  378.  
  379.         return (long)tempcdev;
  380.     }
  381.     
  382.   if ( (long)p != cdevUnset && (long)p != 0L ) {
  383.     
  384.     switch (msg) {
  385.  
  386.     case updateDev:
  387.         updatecp(p, dlogp, numitems);
  388.         break;
  389.         
  390.     case closeDev:
  391.         updateprefs(p);    /* update the preferences file */
  392.         FSClose(p->prefref);    /* close the Preferences file */
  393.         ReleaseResource(p->baud.menuh);
  394.         ReleaseResource(p->port.menuh);
  395.         ReleaseResource(p->idle.menuh);
  396.         ReleaseResource(p->echo.menuh);
  397.         ReleaseResource(p->server.menuh);
  398.         DisposPtr(p);            /* release our memory */
  399.         break;
  400.  
  401.     case hitDev:
  402.         GetDItem(dlogp, item, &type, &itemH, &box);
  403.         switch (item-numitems) {
  404.     
  405.         case SOFTCLOSEBTN:
  406.         case HARDCLOSEBTN:
  407.             if ( Gestalt((OSType) 'PPP ', (long *) &lap) == noErr) {
  408.                 if (lap && lap->lapClose && lap->transProc) {
  409.                     (*(lap->lapClose))(lap);    /* close PPP */
  410.                     if ( (item - numitems) == SOFTCLOSEBTN) {
  411.                         lap->ppp_flags |= CLOSE_PPP;
  412.                         (*(lap->transProc))(TransitionOpen);
  413.                     }
  414.                     updatecp(p, dlogp, numitems);
  415.                 }
  416.             }
  417.             break;
  418.     
  419.         case OPENBTN:
  420.             if ( Gestalt((OSType) 'PPP ', (long *) &lap) == noErr) {
  421.                 if (lap) {
  422.                     if (lap->transProc == nil) {
  423.                         if (noErr == OpenDriver("\p.IPP",&type)) {    /* open TCP */
  424.                         CntrlParam tiopb;
  425. #define ipctlGetAddr        15            /* csCode to get our IP address */
  426. #define ipctlEchoICMP        17            /* send icmp echo */
  427.  
  428.                             bzero((char *)&tiopb, sizeof(tiopb));
  429.                             tiopb.ioCRefNum = type;
  430.                             tiopb.csCode = ipctlGetAddr;
  431.                             PBControl((ParamBlockRec *) &tiopb, false);
  432.                         }
  433.                     } else
  434.                         (*(lap->transProc))(TransitionOpen);
  435.                     updatecp(p, dlogp, numitems);
  436.                 }
  437.             }
  438.             break;
  439.  
  440.         case PORTRECT:
  441.             DoPopUp(&(p->port), p->prefdata.portname);
  442.             drawpopup(&(p->port), dlogp, p->prefdata.portname);
  443.             updateprefs(p);    /* update the preferences file */
  444.             break;
  445.  
  446.         case IDLERECT:
  447.             DoPopInt(&(p->idle), &(p->prefdata.timeout));
  448.             drawpopint(&(p->idle), dlogp, p->prefdata.timeout);
  449.             updateprefs(p);    /* update the preferences file */
  450.             break;
  451.  
  452.         case ECHORECT:
  453.             DoPopInt(&(p->echo), &(p->prefdata.echo));
  454.             drawpopint(&(p->echo), dlogp, p->prefdata.echo);
  455.             updateprefs(p);    /* update the preferences file */
  456.             break;
  457.  
  458.         case SERVERRECT:
  459.             workstr[0] = 0;
  460.             AppendStr(workstr, p->prefcnfg.config_name);
  461.             rv = DoPopUp(&(p->server), workstr);
  462.             if (HiWord(rv) != 0) {
  463.                 p->prefdata.active_config = LoWord(rv) - 1;
  464.                 readconfig(p, p->prefdata.active_config);
  465.                 updateprefs(p);    /* update the preferences file */
  466.             }
  467.             drawpopup(&(p->server), dlogp, workstr);
  468.             break;
  469.  
  470.         case TONE:
  471.             dosetctlval(dlogp, item, 1);
  472.             dosetctlval(dlogp, PULSE + numitems, 0);
  473.             p->prefdata.use_pulse = false;
  474.             updateprefs(p);    /* update the preferences file */
  475.             break;
  476.         
  477.         case PULSE:
  478.             dosetctlval(dlogp, item, 1);
  479.             p->prefdata.use_pulse = true;
  480.             dosetctlval(dlogp, TONE + numitems, 0);
  481.             updateprefs(p);    /* update the preferences file */
  482.             break;
  483.  
  484.         case TERMCHECK:
  485.             SetCtlValue(itemH, (p->prefdata.use_term = GetCtlValue(itemH) ^ 1));
  486.             updateprefs(p);    /* update the preferences file */
  487.             break;
  488.  
  489.         case HANGUPCHECK:
  490.             SetCtlValue(itemH, (p->prefdata.hangup = GetCtlValue(itemH) ^ 1));
  491.             updateprefs(p);    /* update the preferences file */
  492.             break;
  493.  
  494.         case QUIETCHECK:
  495.             SetCtlValue(itemH, (p->prefdata.quiet = GetCtlValue(itemH) ^ 1));
  496.             updateprefs(p);    /* update the preferences file */
  497.             break;
  498.  
  499.         case STATSBTN:
  500.             dostatsdlog();
  501.             break;
  502.  
  503.         case CONFIGBTN:
  504.             doconfigdlog(p);
  505.             updatecp(p, dlogp, numitems);
  506.             break;
  507.  
  508.         default:
  509.             break;
  510.         }
  511.     default:
  512.         break;
  513.     }
  514.   }
  515.   return (long)p;
  516. }
  517.  
  518. void
  519. updatecp(struct cdevstore *p, DialogPtr dlogp, int numitems)
  520. {
  521.     drawpopup(&(p->port), dlogp, p->prefdata.portname);
  522.     drawpopint(&(p->idle), dlogp, p->prefdata.timeout);
  523.     drawpopint(&(p->echo), dlogp, p->prefdata.echo);
  524.     drawpopup(&(p->server), dlogp, p->prefcnfg.config_name);
  525.     setbuttons(dlogp, numitems);
  526. }
  527.  
  528. void
  529. drawpopint(struct popup *p, DialogPtr dlogp, unsigned int value)
  530. {
  531.     char    popstring[24];
  532.     unsigned long tempvalue;
  533.  
  534.     if (value == 0)
  535.         GetItem(p->menuh, 1, popstring); /* use first item if 0 */
  536.     else {
  537.         tempvalue = value;
  538.         NumToString(tempvalue, popstring);
  539.     }
  540.     drawpopup(p, dlogp, popstring);
  541. }
  542.  
  543. void            
  544. drawpopup(struct popup *p, DialogPtr dlogp, char *popstring)
  545. {
  546. int        savfont,savsize,i;
  547. GrafPtr    savport;
  548. Rect    r;
  549.  
  550.     GetPort(&savport);
  551.     SetPort(dlogp);
  552.     savfont = dlogp->txFont;
  553.     savsize = dlogp->txSize;
  554.     TextFont(0);
  555.     TextSize(12);
  556.     p->poprect.bottom++;
  557.     EraseRect(&(p->poprect));
  558.     p->poprect.bottom--;
  559.     /* calc pop up rectangle based on width of menu items */
  560.     SetRect(&r, p->poprect.left,
  561.                 p->poprect.top,
  562.                 p->poprect.left + StringWidth(popstring) + 24,
  563.                 p->poprect.bottom);
  564.                 
  565.     MoveTo(p->titlerect.left, p->titlerect.bottom-4);
  566.     DrawString(&(**p->menuh).menuData);
  567.     MoveTo(p->poprect.left+4,p->poprect.bottom-4);
  568.     DrawString(popstring);
  569.  
  570.     FrameRect(&r);
  571.     /* This must be the stupidest way to shadow a rect */    
  572.     MoveTo(r.left+3, r.bottom);
  573.     LineTo(r.right, r.bottom);
  574.     LineTo(r.right, r.top+3);
  575.     /* draw the menu indicator thingy */
  576.     for (i = 0; i < 6; ++i)    {
  577.         MoveTo(r.right - 10 - i, r.bottom - 7 - i);
  578.         Line(2*i, 0);
  579.     }
  580.     TextFont(savfont);
  581.     TextSize(savsize);
  582.     SetPort(savport);
  583. }
  584.  
  585. void dosetitext(DialogPtr dlogp, int itemnum, char *string)
  586. {
  587. int        type;
  588. Handle    itemH;
  589. Rect    box;
  590.  
  591.     GetDItem(dlogp, itemnum, &type, &itemH, &box);
  592.     SetIText(itemH, string);
  593. }
  594.  
  595. void dosetctlval(DialogPtr dlogp, int itemnum, int value)
  596. {
  597. int        type;
  598. Handle    itemH;
  599. Rect    box;
  600.  
  601.     GetDItem(dlogp, itemnum, &type, &itemH, &box);
  602.     SetCtlValue(itemH, value);
  603. }
  604.  
  605. void dosetilong(DialogPtr dlogp, int itemnum, b_32 value)
  606. {
  607. char    s[12];
  608.  
  609.     NumToString(value, &s);
  610.     dosetitext(dlogp, itemnum, s);
  611. }
  612.  
  613. void dosetipaddr(DialogPtr dlogp, int itemnum, b_32 address)
  614. {
  615. char    s[20];
  616. char    s2[12];
  617. int        i;
  618. unsigned char *ptr = (unsigned char *) &address;
  619.  
  620.     /* display 4 byte num in dot notation */
  621.     s[0] = 0;
  622.     for (i = 0; i<4; i++) {
  623.         NumToString((unsigned long) *ptr++, &s2);
  624.         AppendStr(s, s2);
  625.         AppendStr(s, "\p.");        
  626.     }
  627.     s[0] = s[0] - 1;        /* delete last dot */
  628.     dosetitext(dlogp, itemnum, s);
  629. }
  630.  
  631. void dosethex(DialogPtr dlogp, int itemnum, b_32 value)
  632. {
  633. char s[10];
  634. int i;
  635.  
  636.     s[0] = 8;
  637.     for (i=8; i > 0 ; i--) {
  638.         s[i] = (value & 0xf) + '0';
  639.         if (s[i] > '9')
  640.             s[i] += 7;
  641.         value >>= 4;
  642.     }
  643.     dosetitext(dlogp, itemnum, s);
  644. }
  645.     
  646. void dosetcbox(DialogPtr dlogp, int itemnum, int state)
  647. {
  648. GrafPtr        saveptr;
  649. int            type;
  650. Handle        itemH;
  651. Rect        box;
  652.  
  653.     GetDItem(dlogp, itemnum, &type, &itemH, &box);
  654.     GetPort(&saveptr);
  655.     SetPort(dlogp);
  656.     EraseRect(&box);
  657.     FrameRect(&box);
  658.     if (state) {
  659.         MoveTo(box.left + 1 , box.bottom - 1 );
  660.         LineTo(box.right - 1, box.top );
  661.         MoveTo(box.left , box.top );
  662.         LineTo(box.right -1 , box.bottom -1);
  663.     }
  664.     SetPort(saveptr);
  665. }
  666.  
  667. struct    pppopts {
  668.     int itemnum;
  669.     int optionbit;
  670. };
  671.  
  672. void setlcpboxes(DialogPtr dlogptr, struct lcpconfig *lcpptr,
  673.                  struct pppopts *optsptr)
  674. {
  675. register    int    optval = optsptr->optionbit;
  676. register    int    optitem = optsptr->itemnum;
  677.  
  678.     dosetctlval(dlogptr, optitem++, 
  679.                 (lcpptr->local.want_negotiate & optval) ? 1 : 0);
  680.     dosetctlval(dlogptr, optitem++,
  681.                 (lcpptr->local.will_negotiate & optval) ? 1 : 0);
  682.     dosetctlval(dlogptr, optitem++, 
  683.                 (lcpptr->remote.want_negotiate & optval) ? 1 : 0);
  684.     dosetctlval(dlogptr, optitem++, 
  685.                 (lcpptr->remote.will_negotiate & optval) ? 1 : 0);
  686.  
  687.     switch (optval) {
  688.     case LCP_N_MAGIC:
  689.         dosetilong(dlogptr, optitem++, lcpptr->local.want.magic_number);
  690.         dosetilong(dlogptr, optitem, lcpptr->remote.want.magic_number);
  691.         break;
  692.     case LCP_N_MRU:
  693.         dosetilong(dlogptr, optitem++, (b_32) lcpptr->local.want.mru);
  694.         dosetilong(dlogptr, optitem, (b_32) lcpptr->remote.want.mru);
  695.         break;
  696.     case LCP_N_ACCM:
  697.         dosethex(dlogptr, optitem++, (b_32) lcpptr->local.want.accm);
  698.         dosethex(dlogptr, optitem, (b_32) lcpptr->remote.want.accm);
  699.         break;
  700.     }
  701. }
  702.  
  703. Boolean getlcpboxes(DialogPtr dlogptr, struct lcpconfig *lcpptr,
  704.                  struct pppopts *optsptr)
  705. {
  706. int            type, i, k;
  707. unsigned long lv;
  708. unsigned char digit;
  709. Handle        itemH,litemH,ritemH;
  710. Rect        box;
  711. b_32        mruval;
  712. Str255        s;
  713. register    int    optval = optsptr->optionbit;
  714. register    int    optitem = optsptr->itemnum;
  715.  
  716.     getnegval(dlogptr, optitem++, optval, &(lcpptr->local.want_negotiate));
  717.     getnegval(dlogptr, optitem++, optval, &(lcpptr->local.will_negotiate));
  718.     getnegval(dlogptr, optitem++, optval, &(lcpptr->remote.want_negotiate));
  719.     getnegval(dlogptr, optitem++, optval, &(lcpptr->remote.will_negotiate));
  720.  
  721.     GetDItem(dlogptr, optitem++, &type, &litemH, &box);
  722.     GetDItem(dlogptr, optitem, &type, &ritemH, &box);
  723.     switch (optval) {
  724.     case LCP_N_AUTHENT:    /* we only support PAP, hardcode it */
  725.         lcpptr->remote.want.authentication = PPP_PAP_PROTOCOL;
  726.         break;
  727.     case LCP_N_MAGIC:
  728.         GetIText(litemH, &s);
  729.         StringToNum(s, &(lcpptr->local.want.magic_number));
  730.         GetIText(ritemH, &s);
  731.         StringToNum(s, &(lcpptr->remote.want.magic_number));
  732.         break;
  733.     case LCP_N_ACCM:
  734.         lcpptr->local.want.accm = 0L;
  735.         lcpptr->remote.want.accm = 0L;
  736.         k = optitem - 1;
  737.         while( k <= optitem ) {
  738.             gettext(dlogptr, k, s);
  739.             lv = 0;
  740.             /* convert string from hex to a long int */
  741.             if (s[0] > 8) {    /* too long */
  742.                 MyNoteAlert(ACCMMESS);
  743.                 SelIText(dlogptr, k, 0, 32767);
  744.                 return false;
  745.             }
  746.             for (i = 1; i <= s[0]; i++) {
  747.                 digit = s[i];
  748.                 if (digit > 0x60)
  749.                     digit &= 0xDF;    /* convert to upper case */
  750.                 if (digit >= '0' && digit <= '9') {
  751.                     lv <<= 4;
  752.                     lv += digit - '0';
  753.                 } else if (digit >= 'A' && digit <= 'F') {
  754.                     lv <<= 4;
  755.                     lv += digit - 55;
  756.                 } else {
  757.                     MyNoteAlert(ACCMMESS);
  758.                     SelIText(dlogptr, k, 0, 32767);
  759.                     return false;    /* parse error */
  760.                 }
  761.             }
  762.             if ( k == optitem )
  763.                 lcpptr->remote.want.accm = lv;
  764.             else
  765.                 lcpptr->local.want.accm = lv;
  766.             k++;
  767.         }
  768.         break;
  769.     case LCP_N_MRU:
  770.         GetIText(litemH, &s);
  771.         StringToNum(s, &mruval);
  772.         if ( mruval < LCP_MRU_LO || mruval > LCP_MRU_HI ) {
  773.             MyNoteAlert(MRUMESS);
  774.             SelIText(dlogptr, optitem-1, 0, 32767);
  775.             return false;
  776.         } else
  777.             lcpptr->local.want.mru = mruval;
  778.         GetIText(ritemH, &s);
  779.         StringToNum(s, &mruval);
  780.         if ( mruval < LCP_MRU_LO || mruval > LCP_MRU_HI ) {
  781.             MyNoteAlert(MRUMESS);
  782.             SelIText(dlogptr, optitem, 0, 32767);
  783.             return false;
  784.         } else
  785.             lcpptr->remote.want.mru = mruval;
  786.         break;
  787.     }
  788.     return true;
  789. }
  790.  
  791. void doconfigdlog(struct cdevstore *p) {
  792. DialogPtr    tempdlog, askdlog;
  793. GrafPtr        savport;
  794. char        s[MAXSLEN + 1];
  795. long        numval;
  796. int            curconfig, j, i, type, itemhit;
  797. Handle        itemH;
  798. Rect        box;
  799. Boolean        needupdate = true;
  800.  
  801.     tempdlog = GetNewDialog(CONNECTDLOG, 0L, (WindowPtr) -1L);
  802.     GetPort(&savport);
  803.     SetPort(tempdlog);
  804.     /* get baud rects */
  805.     GetDItem(tempdlog, BAUDRECT, &type, &itemH, &(p->baud.poprect));
  806.     GetDItem(tempdlog, BTITLERECT, &type, &itemH, &(p->baud.titlerect));
  807.  
  808. setconfigs:
  809.     dosetctlval(tempdlog, CTSCHECK, p->prefcnfg.flowctl_on);
  810.     dosetitext(tempdlog, SERVERNAME, p->prefcnfg.config_name);
  811.     dosetitext(tempdlog, MODEMINIT, p->prefcnfg.modeminit);
  812.     dosetitext(tempdlog, PHONENUM, p->prefcnfg.phonenum);
  813.     dosetilong(tempdlog, CONNECTTIME, p->prefcnfg.connecttimeout);
  814.     SelIText(tempdlog, SERVERNAME, 0, 32767);
  815.     curconfig = p->prefdata.active_config;
  816.  
  817.     while (true) {
  818.         if (needupdate)
  819.             drawpopint(&(p->baud), tempdlog, p->prefcnfg.baudrate);
  820.         ModalDialog(dumbfilter, &itemhit);
  821.         needupdate = true;
  822.  
  823.         if (itemhit == LCPBTN || itemhit == IPCPBTN) {
  824.             if ((itemhit) == LCPBTN) 
  825.                 dolcpdlog(p);
  826.             else
  827.                 doipcpdlog(p);
  828.         } else if (itemhit == AUTHBTN) {
  829.             doauthdlog(p);
  830.         } else if (itemhit == SCRIPTBTN) {
  831.             doscriptdlog(p);
  832.         } else if (itemhit == BAUDRECT) {
  833.             DoPopInt(&(p->baud), &(p->prefcnfg.baudrate));
  834.         } else if (itemhit == CTSCHECK) {
  835.             GetDItem(tempdlog, itemhit, &type, &itemH, &box);
  836.             SetCtlValue(itemH, (p->prefcnfg.flowctl_on = GetCtlValue(itemH) ^ 1));
  837.             needupdate = false;
  838.         } else if (itemhit == DELETESERVER) {
  839.             if (p->prefdata.max_config == 1) {
  840.                 MyNoteAlert(CONFIGMESS);
  841.                 continue;
  842.             }
  843.             if (!gettext(tempdlog, SERVERNAME, p->prefcnfg.config_name))
  844.                 continue;
  845.             ParamText(p->prefcnfg.config_name, "\p", "\p", "\p");
  846.             askdlog = GetNewDialog(ASKDLOG, 0L, (WindowPtr) -1L);
  847.             do {
  848.                 ModalDialog(nil, &itemhit);
  849.             } while (itemhit == 0);
  850.             DisposDialog(askdlog);
  851.             if (itemhit != OK)
  852.                 continue;
  853.             ReleaseResource(p->server.menuh);
  854.             p->server.menuh = GetMenu(SERVERMENU);
  855.             --(p->prefdata.max_config);
  856.             p->prefdata.active_config = 0;
  857.             i = 1;
  858.             for (j = 0 ; j <= p->prefdata.max_config; j++ ) {
  859.                 readconfig(p, j);
  860.                 if (j == curconfig)
  861.                     continue;
  862.                 updateprefs(p);
  863.                 (p->prefdata.active_config)++;
  864.                 AppendMenu(p->server.menuh, "\p ");
  865.                 SetItem(p->server.menuh, i, p->prefcnfg.config_name);
  866.                 i++;
  867.             }
  868.             if ( curconfig == p->prefdata.max_config )
  869.                 --curconfig;
  870.             p->prefdata.active_config = curconfig;
  871.             readconfig(p, curconfig);
  872.             goto setconfigs;
  873.         } else if (itemhit == OK || itemhit == NEWSERVER) {
  874.             /* read boxes and set resource fields */
  875.             if (!gettext(tempdlog, MODEMINIT, p->prefcnfg.modeminit))
  876.                 continue;
  877.             if (!gettext(tempdlog, PHONENUM, p->prefcnfg.phonenum))
  878.                 continue;
  879.             if (!gettext(tempdlog, SERVERNAME, p->prefcnfg.config_name))
  880.                 continue;
  881.             if (p->prefcnfg.config_name[0] == 0) {
  882.                 MyNoteAlert(NULLMESS);
  883.                 SelIText(tempdlog, SERVERNAME, 0, 32767);
  884.                 continue;
  885.             }            
  886.             for (j = 1 ; j <= p->prefdata.max_config; j++ ) {
  887.                 if (j == curconfig + 1)
  888.                     continue;
  889.                 GetItem(p->server.menuh, j, s);
  890.                 if (EqualString(s, p->prefcnfg.config_name, true, false)) {
  891.                     MyNoteAlert(SAMEMESS);
  892.                     goto setconfigs;
  893.                 }
  894.             }
  895.             SetItem(p->server.menuh, curconfig + 1, p->prefcnfg.config_name);
  896.             if (!gettext(tempdlog, CONNECTTIME, s))
  897.                 continue;
  898.             StringToNum(s, &numval);
  899.             p->prefcnfg.connecttimeout = LoWord(numval);
  900.             updateprefs(p);
  901.             if (itemhit == OK )
  902.                 break;
  903.             /* we are adding a new server entry, init a new entry */
  904.             p->prefdata.active_config = p->prefdata.max_config++;
  905.             AppendMenu(p->server.menuh,"\p ");
  906.             initconfigs(p);
  907.             updateprefs(p);
  908.             goto setconfigs;
  909.         } else
  910.             needupdate = false;
  911.     }
  912.     DisposDialog(tempdlog);
  913.     SetPort(savport);
  914. }
  915.  
  916. void doauthdlog(struct cdevstore *p) {
  917. pascal        Boolean authfilter(DialogPtr, EventRecord *, int *);
  918. DialogPtr    tempdlog;
  919. struct         mydlogrec authdlogrec;
  920. int            itemhit;
  921. char        s[MAXSLEN + 1];
  922. int            strlen;
  923.  
  924.     tempdlog = GetNewDialog(AUTHDLOG, &authdlogrec, (WindowPtr) -1L);
  925.  
  926.     dosetitext(tempdlog, AUTHID, p->prefcnfg.defaultid);
  927.     strlen = (s[0] = p->prefcnfg.defaultpw[0]);
  928.     while (strlen > 0)
  929.         s[strlen--] = 'Ñ';
  930.     dosetitext(tempdlog, AUTHPW, s);
  931.     s[0] = 0;
  932.     AppendStr(s, p->prefcnfg.defaultpw);
  933.     authdlogrec.strptr = s;
  934.     dosetilong(tempdlog, AUTHRETRIES, (b_32) p->prefcnfg.pap_retries);
  935.     dosetilong(tempdlog, AUTHTIMEOUT, (b_32) p->prefcnfg.pap_timeout);
  936.     
  937.     do {
  938.         ModalDialog(authfilter, &itemhit);
  939.         if (itemhit == OK) {
  940.             if (!gettext(tempdlog, AUTHID, p->prefcnfg.defaultid))
  941.                 continue;
  942.             if (!getbyte(tempdlog, AUTHRETRIES, &(p->prefcnfg.pap_retries)))
  943.                 continue;
  944.             if (!getbyte(tempdlog, AUTHTIMEOUT, &(p->prefcnfg.pap_timeout)))
  945.                 continue;
  946.             strlen = p->prefcnfg.defaultpw[0];
  947.             while (strlen >= 0)
  948.                 p->prefcnfg.defaultpw[strlen--] = 0; /* clear old string */
  949.             AppendStr(p->prefcnfg.defaultpw, s);
  950.             break;
  951.         }
  952.     } while (itemhit != Cancel);
  953.     CloseDialog(tempdlog);
  954. }
  955.  
  956. void doscriptdlog(struct cdevstore *p) {
  957. pascal        Boolean scriptfilter(DialogPtr, EventRecord *, int *);
  958. DialogPtr    tempdlog;
  959. char        s[MAXSLEN + 1];
  960. long        numval;
  961. int            i, type, itemhit;
  962. Handle        itemH;
  963. Rect        box;
  964.  
  965.     tempdlog = GetNewDialog(SCRIPTDLOG, 0L, (WindowPtr) -1L);
  966.     dosetilong(tempdlog, WAITTIME, p->prefcnfg.waittimeout);
  967.  
  968.     for (i = 0 ; i < NUMCOMMANDS; i++ ) {
  969.         dosetitext(tempdlog, COMMANDS + i, p->prefcnfg.commands[i].scriptstr);
  970.         dosetctlval(tempdlog, ADDRETURNS + i, p->prefcnfg.commands[i].addreturn);
  971.         itemhit = COMMANDBTNS + i*2;
  972.         if (!p->prefcnfg.commands[i].sendout)
  973.             itemhit++;
  974.         dosetctlval(tempdlog, itemhit, 1);
  975.     }
  976. scriptretry:
  977.     do {
  978.         ModalDialog(scriptfilter, &itemhit);
  979.     
  980.         if (itemhit >= COMMANDBTNS && itemhit < (COMMANDBTNS +NUMCOMMANDS * 2) ) {
  981.             dosetctlval(tempdlog, itemhit, 1);
  982.             dosetctlval(tempdlog, COMMANDBTNS + ((itemhit - COMMANDBTNS) ^ 1), 0);
  983.         }
  984.         if (itemhit >= ADDRETURNS && itemhit < (ADDRETURNS + NUMCOMMANDS) ) {
  985.             GetDItem(tempdlog, itemhit, &type, &itemH, &box);
  986.             SetCtlValue(itemH, (GetCtlValue(itemH) ^ 1));
  987.         }
  988.  
  989.         if (itemhit == OK) {
  990.             for (i = 0 ; i < NUMCOMMANDS; i++ ) {
  991.                 if (!gettext(tempdlog, COMMANDS+i, p->prefcnfg.commands[i].scriptstr))
  992.                     goto scriptretry;
  993.                 GetDItem(tempdlog,ADDRETURNS + i,&type,&itemH,&box);
  994.                 p->prefcnfg.commands[i].addreturn = GetCtlValue(itemH);
  995.                 GetDItem(tempdlog,COMMANDBTNS + i*2,&type,&itemH,&box);
  996.                 p->prefcnfg.commands[i].sendout = GetCtlValue(itemH);
  997.             }
  998.             if (!gettext(tempdlog, WAITTIME, s))
  999.                 goto scriptretry;
  1000.             StringToNum(s, &numval);
  1001.             p->prefcnfg.waittimeout = LoWord(numval);
  1002.             break;
  1003.         }
  1004.     } while (itemhit != Cancel);
  1005.     DisposDialog(tempdlog);
  1006. }
  1007.  
  1008. void dostatsdlog() {
  1009. LapInfo        *lap;
  1010. DialogPtr    tempdlog;
  1011. int            itemhit;
  1012.  
  1013.     if ( Gestalt((OSType) 'PPP ', (long *) &lap) != noErr)
  1014.         return;
  1015.     tempdlog = GetNewDialog(STATSDLOG, 0L, (WindowPtr) -1L);
  1016. updatestats:    
  1017.     dosetilong(tempdlog, INOCTETS, lap->InRxOctetCount);
  1018.     dosetilong(tempdlog, OUTOCTETS, lap->OutTxOctetCount);
  1019.     dosetilong(tempdlog, INPACKETS, lap->InOpenFlag);
  1020.     dosetilong(tempdlog, OUTPACKETS, lap->OutOpenFlag);
  1021.     dosetilong(tempdlog, CHECKSEQERRS, (b_32) lap->InCheckSeq);
  1022.     dosetilong(tempdlog, HEADERERRS, (b_32) lap->InHeader);
  1023.     dosetilong(tempdlog, HWOVERRUNS, (b_32) lap->InHardOvr);
  1024.     dosetilong(tempdlog, SWOVERRUNS, (b_32) lap->InSoftOvr);
  1025.     dosetilong(tempdlog, FRAMINGERRS, (b_32) lap->InFramingErr);
  1026.     dosetilong(tempdlog, OUTOFBUFS, (b_32) lap->OutofBuffers);
  1027.     dosetcbox(tempdlog, PFCVALS,lap->lcp_i.local.work_negotiate & LCP_N_PFC);
  1028.     dosetcbox(tempdlog, PFCVALS + 1, lap->lcp_i.remote.work_negotiate & LCP_N_PFC);
  1029.     dosetcbox(tempdlog, ACFCVALS, lap->lcp_i.local.work_negotiate & LCP_N_ACFC);
  1030.     dosetcbox(tempdlog, ACFCVALS + 1, lap->lcp_i.remote.work_negotiate & LCP_N_ACFC);
  1031.     dosetcbox(tempdlog, PAPVALS, lap->lcp_i.local.work_negotiate & LCP_N_AUTHENT);
  1032.     dosetcbox(tempdlog, PAPVALS + 1, lap->lcp_i.remote.work_negotiate & LCP_N_AUTHENT);
  1033.     dosethex(tempdlog, MAGICVALS, lap->lcp_i.local.work.lcp_option.magic_number);
  1034.     dosethex(tempdlog, MAGICVALS + 1, lap->lcp_i.remote.work.lcp_option.magic_number);
  1035.     dosethex(tempdlog, ACCMVALS, lap->lcp_i.local.work.lcp_option.accm);
  1036.     dosethex(tempdlog, ACCMVALS + 1, lap->lcp_i.remote.work.lcp_option.accm);
  1037.     dosetilong(tempdlog, MRUVALS, lap->lcp_i.local.work.lcp_option.mru);
  1038.     dosetilong(tempdlog, MRUVALS + 1, lap->lcp_i.remote.work.lcp_option.mru);
  1039.     dosetcbox(tempdlog, VJVALS,lap->ipcp_i.local.work_negotiate & IPCP_N_COMPRESS);
  1040.     dosetcbox(tempdlog, VJVALS + 1, lap->ipcp_i.remote.work_negotiate & IPCP_N_COMPRESS);
  1041.     dosetilong(tempdlog, VJSLOTS, lap->ipcp_i.local.work.ipcp_option.slots);
  1042.     dosetilong(tempdlog, VJSLOTS + 1,lap->ipcp_i.remote.work.ipcp_option.slots);
  1043.     dosetcbox(tempdlog, VJCID,lap->ipcp_i.local.work.ipcp_option.slot_compress);
  1044.     dosetcbox(tempdlog, VJCID + 1, lap->ipcp_i.remote.work.ipcp_option.slot_compress);
  1045.     dosetipaddr(tempdlog, IPADDRVALS, lap->ipcp_i.local.work.ipcp_option.address);
  1046.     dosetipaddr(tempdlog, IPADDRVALS + 1, lap->ipcp_i.remote.work.ipcp_option.address);
  1047.     do {
  1048.         ModalDialog(nil, &itemhit);
  1049.         if (itemhit == UPDATEBTN)
  1050.             goto updatestats;
  1051.     } while (itemhit != OK);
  1052.     DisposDialog(tempdlog);
  1053. }
  1054. #define NUMLCPOPTS 6
  1055.  
  1056. void dolcpdlog(struct cdevstore *p)
  1057. {
  1058. DialogPtr    optsdlog;
  1059. Str255        s;
  1060. int            type, i, itemhit, ctlvalue;
  1061. Handle        itemH;
  1062. Rect        box;
  1063. struct    pppopts    options[NUMLCPOPTS];
  1064.  
  1065.     options[0].itemnum = PFCBOXES;
  1066.     options[0].optionbit = LCP_N_PFC;
  1067.     options[1].itemnum = ACFCBOXES;
  1068.     options[1].optionbit = LCP_N_ACFC;
  1069.     options[2].itemnum = AUTHENTBOXES;
  1070.     options[2].optionbit = LCP_N_AUTHENT;
  1071.     options[3].itemnum = MAGICBOXES;
  1072.     options[3].optionbit = LCP_N_MAGIC;
  1073.     options[4].itemnum = ACCMBOXES;
  1074.     options[4].optionbit = LCP_N_ACCM;
  1075.     options[5].itemnum = MRUBOXES;
  1076.     options[5].optionbit = LCP_N_MRU;
  1077.  
  1078.     optsdlog = GetNewDialog(LCPDLOG, 0L, (WindowPtr) -1L);
  1079.     
  1080.     for ( i=0 ; i < NUMLCPOPTS; i++ )
  1081.         setlcpboxes(optsdlog, &(p->prefcnfg.lcpconf), &options[i]);
  1082.     dosetilong(optsdlog, LCPRETRIES, (b_32) p->prefcnfg.lcpconf.req_tries);
  1083.     dosetilong(optsdlog, LCPTIMEOUT, (b_32) p->prefcnfg.lcpconf.timeout);
  1084.     do {
  1085. dolcpdlog:                
  1086.         ModalDialog(dumbfilter, &itemhit);
  1087.         for ( i=0 ; i < NUMLCPOPTS; i++ ) {
  1088.             if (itemhit >= options[i].itemnum && 
  1089.                 itemhit < options[i].itemnum + 4) {
  1090.                 GetDItem(optsdlog, itemhit, &type, &itemH, &box);
  1091.                 SetCtlValue(itemH, (ctlvalue = GetCtlValue(itemH) ^ 1));
  1092.                 switch (itemhit - options[i].itemnum) {
  1093.                 case 0:
  1094.                 case 2:
  1095.                     if (ctlvalue) {
  1096.                         dosetctlval(optsdlog, itemhit+1, 1);
  1097.                     }
  1098.                     break;
  1099.                 case 1:
  1100.                 case 3:
  1101.                     if (!ctlvalue) {
  1102.                         dosetctlval(optsdlog, itemhit-1, 0);
  1103.                     }
  1104.                 }
  1105.                 break;
  1106.             }
  1107.         }
  1108.         if (itemhit == LCPDEFAULT) {
  1109.             for ( i=0 ; i < NUMLCPOPTS; i++ )
  1110.                 setlcpboxes(optsdlog, &(p->deflcp), &options[i]);
  1111.             dosetilong(optsdlog, LCPRETRIES, (b_32) p->deflcp.req_tries);
  1112.             dosetilong(optsdlog, LCPTIMEOUT, (b_32) p->deflcp.timeout);
  1113.         }
  1114.         if (itemhit == OK) {
  1115.             for ( i=0 ; i < NUMLCPOPTS; i++ ) {
  1116.                 if (!getlcpboxes(optsdlog, &(p->prefcnfg.lcpconf), &options[i]))
  1117.                     goto dolcpdlog;
  1118.             }
  1119.             if (!getbyte(optsdlog, LCPRETRIES, &(p->prefcnfg.lcpconf.req_tries)))
  1120.                 goto dolcpdlog;
  1121.             if (!getbyte(optsdlog, LCPTIMEOUT, &(p->prefcnfg.lcpconf.timeout)))
  1122.                 goto dolcpdlog;
  1123.             updateprefs(p);
  1124.             break;
  1125.         }
  1126.     }
  1127.     while (itemhit != Cancel);
  1128.  
  1129.     DisposDialog(optsdlog);
  1130. }
  1131.  
  1132. void setipcpboxes(DialogPtr dlogptr, struct ipcpconfig *ipcpptr,
  1133.                  struct pppopts *optsptr)
  1134. {
  1135. register int    optval = optsptr->optionbit;
  1136. register int    optitem = optsptr->itemnum;
  1137.  
  1138.     dosetctlval(dlogptr, optitem++,
  1139.                 (ipcpptr->local.want_negotiate & optval) ? 1 : 0);
  1140.     dosetctlval(dlogptr, optitem++,
  1141.                 (ipcpptr->local.will_negotiate & optval) ? 1 : 0);
  1142.     dosetctlval(dlogptr, optitem++,
  1143.                 (ipcpptr->remote.want_negotiate & optval) ? 1 : 0);
  1144.     dosetctlval(dlogptr, optitem++,
  1145.                 (ipcpptr->remote.will_negotiate & optval) ? 1 : 0);
  1146.  
  1147.     switch (optval) {
  1148.     case IPCP_N_ADDRESS:
  1149.         dosetipaddr(dlogptr, optitem++, ipcpptr->local.want.address);
  1150.         dosetipaddr(dlogptr, optitem, ipcpptr->remote.want.address);
  1151.         break;
  1152.     };
  1153. }
  1154.  
  1155. Boolean getipcpboxes(DialogPtr dlogptr, struct ipcpconfig *ipcpptr,
  1156.                  struct pppopts *optsptr)
  1157. {
  1158. int            type, i, j, k;
  1159. unsigned long    lv;
  1160. char        *ptr;
  1161. Str255        s;
  1162. Str32        s2;
  1163. register    int    optval = optsptr->optionbit;
  1164. register    int    optitem = optsptr->itemnum;
  1165.  
  1166.     getnegval(dlogptr, optitem++, optval, &(ipcpptr->local.want_negotiate));
  1167.     getnegval(dlogptr, optitem++, optval, &(ipcpptr->local.will_negotiate));
  1168.     getnegval(dlogptr, optitem++, optval, &(ipcpptr->remote.want_negotiate));
  1169.     getnegval(dlogptr, optitem++, optval, &(ipcpptr->remote.will_negotiate));
  1170.  
  1171.     switch (optval) {
  1172.     case IPCP_N_ADDRESS:
  1173.         /* accept both forms of address negotiation */
  1174.         if (ipcpptr->local.will_negotiate & IPCP_N_ADDRESS)
  1175.             ipcpptr->local.will_negotiate | IPCP_N_ADDRESSES;
  1176.         else
  1177.             ipcpptr->local.will_negotiate & ~IPCP_N_ADDRESSES;
  1178.             
  1179.         if (ipcpptr->remote.will_negotiate & IPCP_N_ADDRESS)
  1180.             ipcpptr->remote.will_negotiate | IPCP_N_ADDRESSES;
  1181.         else
  1182.             ipcpptr->remote.will_negotiate & ~IPCP_N_ADDRESSES;
  1183.             
  1184.         ipcpptr->local.want.address = 0L;
  1185.         ipcpptr->remote.want.address = 0L;
  1186.         ipcpptr->local.want.other = 0L;
  1187.         ipcpptr->remote.want.other = 0L;
  1188.         k = optitem++;
  1189.         while( k <= optitem ) {
  1190.             gettext(dlogptr, k, s);
  1191.             /* convert string from dot notation to a long int */
  1192.             ptr = &s[1];
  1193.             s[s[0]+1] = '.';
  1194.             for (j = 3; j >= 0; j--) {
  1195.                 s2[0] = 0;
  1196.                 for (i = 1; *ptr != '.'; i++) {
  1197.                     if ((ptr > s + s[0]) || (*ptr > '9') || (*ptr < '0')){
  1198.                         MyNoteAlert(IPMESS);
  1199.                         SelIText(dlogptr, k, 0, 32767);
  1200.                         return false;    /* parse error */
  1201.                     }
  1202.                     s2[i] = *ptr++;
  1203.                     s2[0]++;
  1204.                 }
  1205.                 ptr++;
  1206.                 StringToNum(s2, &lv);
  1207.                 if (lv > 255) {
  1208.                     MyNoteAlert(IPMESS);
  1209.                     SelIText(dlogptr, k, 0, 32767);
  1210.                     return false;    /* parse error */
  1211.                 }
  1212.                 lv <<= j*8;
  1213.                 if ( k == optitem ) {
  1214.                     ipcpptr->remote.want.address |= lv;
  1215.                     ipcpptr->local.want.other |= lv;
  1216.                 } else {
  1217.                     ipcpptr->local.want.address |= lv;
  1218.                     ipcpptr->remote.want.other |= lv;
  1219.                 }
  1220.             }
  1221.             k++;
  1222.         }
  1223.         break;
  1224.     }
  1225.     return true;
  1226. }
  1227.  
  1228. #define NUMIPCPOPTS 2
  1229.  
  1230. void doipcpdlog(struct cdevstore *p)
  1231. {
  1232. DialogPtr    optsdlog;
  1233. Str255        s;
  1234. int            type, i, itemhit, ctlvalue;
  1235. Handle        itemH;
  1236. Rect        box;
  1237. struct    pppopts    options[NUMIPCPOPTS];
  1238.  
  1239.     options[0].itemnum = COMPRESSBOXES;
  1240.     options[0].optionbit = IPCP_N_COMPRESS;
  1241.     options[1].itemnum = ADDRESSBOXES;
  1242.     options[1].optionbit = IPCP_N_ADDRESS;
  1243.  
  1244.     optsdlog = GetNewDialog(IPCPDLOG, 0L, (WindowPtr) -1L);
  1245.     for ( i=0 ; i < NUMIPCPOPTS; i++ )
  1246.         setipcpboxes(optsdlog, &(p->prefcnfg.ipcpconf), &options[i]);
  1247.     dosetilong(optsdlog, IPCPRETRIES, (b_32) p->prefcnfg.ipcpconf.req_tries);
  1248.     dosetilong(optsdlog, IPCPTIMEOUT, (b_32) p->prefcnfg.ipcpconf.timeout);
  1249.     do {                
  1250. doipcpdlog:
  1251.         ModalDialog(dumbfilter, &itemhit);
  1252.         for ( i=0 ; i < NUMIPCPOPTS; i++ ) {
  1253.             if (itemhit >= options[i].itemnum && 
  1254.                 itemhit < options[i].itemnum + 4) {
  1255.                 GetDItem(optsdlog, itemhit, &type, &itemH, &box);
  1256.                 SetCtlValue(itemH, (ctlvalue = GetCtlValue(itemH) ^ 1));
  1257.                 switch (itemhit - options[i].itemnum) {
  1258.                 case 0:
  1259.                 case 2:
  1260.                     if (ctlvalue) {
  1261.                         dosetctlval(optsdlog, itemhit+1, 1);
  1262.                     }
  1263.                     break;
  1264.                 case 1:
  1265.                 case 3:
  1266.                     if (!ctlvalue) {
  1267.                         dosetctlval(optsdlog, itemhit-1, 0);
  1268.                     }
  1269.                 }
  1270.                 break;
  1271.             }
  1272.         }
  1273.         if (itemhit == IPCPDEFAULT) {
  1274.             for ( i=0 ; i < NUMIPCPOPTS; i++ )
  1275.                 setipcpboxes(optsdlog, &(p->defipcp), &options[i]);
  1276.             dosetilong(optsdlog, IPCPRETRIES, (b_32) p->defipcp.req_tries);
  1277.             dosetilong(optsdlog, IPCPTIMEOUT, (b_32) p->defipcp.timeout);
  1278.         }
  1279.     }
  1280.     while (itemhit != OK && itemhit != Cancel);
  1281.     if (itemhit == OK) {
  1282.         for ( i=0 ; i < NUMIPCPOPTS; i++ ) {
  1283.             if (!getipcpboxes(optsdlog, &(p->prefcnfg.ipcpconf), &options[i]))
  1284.                 goto doipcpdlog;
  1285.         }
  1286.         if (!getbyte(optsdlog, IPCPRETRIES, &(p->prefcnfg.ipcpconf.req_tries)))
  1287.             goto doipcpdlog;
  1288.         if (!getbyte(optsdlog, IPCPTIMEOUT, &(p->prefcnfg.ipcpconf.timeout)))
  1289.             goto doipcpdlog;
  1290.         updateprefs(p);
  1291.     }
  1292.     DisposDialog(optsdlog);
  1293. }
  1294.  
  1295. void getnegval(DialogPtr dlogptr, int itemnum, int optval, int *optptr)
  1296. {
  1297. int            type;
  1298. Handle        itemH;
  1299. Rect        box;
  1300.  
  1301.     GetDItem(dlogptr, itemnum, &type, &itemH, &box);
  1302.     if (GetCtlValue(itemH))
  1303.         *optptr |= optval;
  1304.     else
  1305.         *optptr &= ~optval;
  1306. }
  1307.  
  1308. long DoPopInt(struct popup *p, unsigned int *value)
  1309. {
  1310.     long rv;
  1311.     char valstring[24];
  1312.     unsigned long tempval;
  1313.     
  1314.     tempval = *value;
  1315.     NumToString(tempval, valstring);
  1316.     rv = DoPopUp(p, valstring);
  1317.     if (HiWord(rv) != 0) {
  1318.         if (valstring[1] < '0' || valstring[1] > '9' )
  1319.             *value = 0;
  1320.         else {
  1321.             StringToNum(valstring, &tempval);
  1322.             *value = LoWord(tempval);
  1323.         }
  1324.     }
  1325.     return rv;
  1326. }
  1327.  
  1328. long DoPopUp(struct popup *p, char *nameptr)
  1329. {
  1330.     long    rv;
  1331.     int        mitems;
  1332.     char    istring[64];
  1333.     Point    where;
  1334.     
  1335.     where.h = p->poprect.left;
  1336.     where.v = p->poprect.top;
  1337.     p->poprect.bottom++;
  1338.     EraseRect(&(p->poprect));
  1339.     p->poprect.bottom--;
  1340.     LocalToGlobal(&(where));
  1341.     mitems = CountMItems(p->menuh);
  1342.     while (mitems > 0) {
  1343.         GetItem(p->menuh, mitems, istring);
  1344.         if (EqualString(istring, nameptr, FALSE, FALSE))
  1345.             break;
  1346.         mitems--;
  1347.     }
  1348.     if (mitems == 0)
  1349.         mitems = 1;
  1350.         
  1351.     InvertRect(&(p->titlerect));
  1352.     InsertMenu(p->menuh, -1);
  1353.     rv = PopUpMenuSelect(p->menuh, where.v, where.h, mitems);
  1354.     DeleteMenu((*(p->menuh))->menuID);
  1355.     InvertRect(&(p->titlerect));
  1356.     if (HiWord(rv) != 0)
  1357.         GetItem(p->menuh, LoWord(rv), nameptr);
  1358.     return rv;
  1359. }
  1360.  
  1361. OSErr readconfig( struct cdevstore *storptr, int confignum )
  1362. {
  1363. long    count;
  1364. OSErr    rc;
  1365.  
  1366.     rc = SetFPos(storptr->prefref,fsFromStart,
  1367.         sizeof(struct ppp_pref) + sizeof (struct ppp_config) * confignum);
  1368.     count = sizeof ( struct ppp_config );
  1369.     if ( rc == noErr)
  1370.         rc = FSRead(storptr->prefref, &count, &(storptr->prefcnfg));
  1371.     if (rc != noErr)
  1372.         MyNoteAlert(PREFSRMESS);
  1373.     return rc;
  1374. }
  1375.  
  1376. OSErr updateprefs( struct cdevstore *storptr )
  1377. {
  1378. long    count, index;
  1379. OSErr    rc;
  1380.  
  1381.     rc = SetFPos(storptr->prefref,fsFromStart,0L);    /* start at beginning */
  1382.     count = sizeof(struct ppp_pref);
  1383.     if ( rc == noErr )
  1384.         rc = FSWrite(storptr->prefref, &count, &(storptr->prefdata));
  1385.     count = sizeof (struct ppp_config);
  1386.     index = storptr->prefdata.active_config * count;
  1387.     if ( rc == noErr )
  1388.         rc = SetFPos(storptr->prefref,fsFromMark,index);
  1389.     if ( rc == noErr )
  1390.         rc = FSWrite(storptr->prefref, &count, &(storptr->prefcnfg));
  1391.     if (rc != noErr)
  1392.         MyNoteAlert(PREFSWMESS);
  1393.     return rc;
  1394. }
  1395.  
  1396. Boolean getbyte(DialogPtr dlogptr, int itemnum, b_8 *byte)
  1397. {
  1398. Str255    s;
  1399. long    numval;
  1400.  
  1401.     if (!gettext(dlogptr, itemnum, s))
  1402.         return false;
  1403.     StringToNum(s, &numval);
  1404.     *byte = numval & 0xff;
  1405.     return true;
  1406. }
  1407.  
  1408. Boolean gettext(DialogPtr dlogptr, int itemnum, char *textptr)
  1409. {
  1410. Str255    s;
  1411. int        type, i, itemhit;
  1412. Handle    itemH;
  1413. Rect    box;
  1414.  
  1415.     GetDItem(dlogptr, itemnum, &type, &itemH, &box);
  1416.     GetIText(itemH, &s);
  1417.     if (s[0] > MAXSLEN) {
  1418.         MyNoteAlert(STRINGMESS);
  1419.         SelIText(dlogptr, itemnum, 0, 32767);
  1420.         return false;
  1421.     } else {
  1422.         *textptr = 0;
  1423.         AppendStr(textptr, s);
  1424.         return true;
  1425.     }
  1426. }
  1427.  
  1428. void setbuttons(DialogPtr dlogp, int numitems)
  1429. {
  1430. LapInfo *lap;
  1431. int    type;
  1432. Rect box,iconrect;
  1433. Handle itemH1, itemH2, itemH3, tempH;        
  1434.  
  1435.     GetDItem(dlogp, numitems + PPPICON, &type, &tempH, &iconrect);
  1436.     GetDItem(dlogp, numitems + OPENBTN, &type, &itemH1, &box);
  1437.     GetDItem(dlogp, numitems + SOFTCLOSEBTN, &type, &itemH2, &box);
  1438.     GetDItem(dlogp, numitems + HARDCLOSEBTN, &type, &itemH3, &box);
  1439.     if ( Gestalt((OSType) 'PPP ', (long *) &lap) == noErr) {
  1440.         if (lap != nil) {
  1441.             if  (lap->ppp_fsm[IPcp].state == fsmOPENED ) {
  1442.                 tempH = GetIcon(PPPUPICON);
  1443.                 PlotIcon(&iconrect, tempH);
  1444.                 ReleaseResource(tempH);
  1445.                 HiliteControl(itemH3, 0);
  1446.                 HiliteControl(itemH2, 0);
  1447.                 HiliteControl(itemH1, 255);
  1448.                 return;
  1449.             } else {
  1450.                 HiliteControl(itemH1, 0);
  1451.                 goto buttonjmp;
  1452.             }
  1453.         }
  1454.     }
  1455.     HiliteControl(itemH1, 255);    /* buttons are inactive */
  1456. buttonjmp:
  1457.     HiliteControl(itemH2, 255);
  1458.     HiliteControl(itemH3, 255);
  1459.     tempH = GetIcon(PPPDOWNICON);
  1460.     PlotIcon(&iconrect, tempH);
  1461.     ReleaseResource(tempH);
  1462. }
  1463.  
  1464. main()
  1465. {}
  1466.  
  1467. pascal Boolean authfilter(DialogPtr dlog, EventRecord *evt, int *itemhit)
  1468. {
  1469.     short        itemType;
  1470.     Handle        itemHdl;
  1471.     Rect        itemRect;
  1472.     int c,i;
  1473.     char        *charptr;
  1474.     char        s[MAXSLEN + 1];
  1475.     
  1476.     charptr = ( (struct mydlogrec *) dlog)->strptr;
  1477.     c = evt->message & charCodeMask;
  1478.     
  1479.     if ( ((DialogPeek) dlog)->editField + 1 == AUTHPW ) {
  1480.       switch(evt->what) {
  1481.         case keyDown:
  1482.         case autoKey:
  1483.             if (c > 31) {
  1484.                 if (*charptr < MAXSLEN)
  1485.                      *( charptr + ++(*charptr) )= c;
  1486.                 *itemhit = 0;
  1487.             }
  1488.             else if (c == 13) {
  1489.                 *itemhit = OK;
  1490.             }
  1491.             else if (c == 8) {
  1492.                 if (*charptr > 0)
  1493.                     (*charptr)--;
  1494.                 *itemhit = 0;
  1495.             }
  1496.             GetDItem(dlog, AUTHPW, &itemType, &itemHdl, &itemRect);
  1497.             i = s[0] = *charptr;
  1498.             while ( i > 0 )
  1499.                 s[i--] = 'Ñ';
  1500.             SetIText(itemHdl, s);
  1501.             SelIText(dlog, AUTHPW, 32767, 32767);
  1502.             return(true);
  1503.             break;
  1504.       }
  1505.     } else if ( ((DialogPeek) dlog)->editField + 1 == AUTHID ) {
  1506.         switch(evt->what) {
  1507.             case keyDown:
  1508.             case autoKey:
  1509.                 if (c == 13 || c == 9) {
  1510.                     *itemhit = AUTHPW;
  1511.                     SelIText(dlog, AUTHPW, 0, 32767);
  1512.                     return(true);
  1513.                 }
  1514.                 break;
  1515.         }
  1516.     }
  1517.     
  1518.     *itemhit=0;
  1519.     return(false);                
  1520. }
  1521.  
  1522. pascal Boolean scriptfilter(DialogPtr dlog, EventRecord *evt, int *itemhit)
  1523. {
  1524.     int c;
  1525.  
  1526.     switch(evt->what) {
  1527.     case keyDown:
  1528.     case autoKey:
  1529.         c = evt->message & charCodeMask;
  1530.         if ( c == 8 || ( c >= 28 && c <= 31 ) || c > 31 )
  1531.             break;
  1532.         if ( c == 13 || c == 9 ) {
  1533.             switch ( ((DialogPeek) dlog)->editField + 1 ) {
  1534.                 case WAITTIME:
  1535.                     SelIText(dlog, COMMANDS, 0, 32767);
  1536.                     break;
  1537.                 case (COMMANDS + NUMCOMMANDS - 1):
  1538.                     if (c == 13)
  1539.                         *itemhit = 1;
  1540.                     else
  1541.                         SelIText(dlog, WAITTIME, 0, 32767);
  1542.                     break;
  1543.                 default:
  1544.                     SelIText(dlog, ((DialogPeek) dlog)->editField + 2, 0, 32767);
  1545.             }
  1546.         }
  1547.         return true;
  1548.     }                            
  1549.     return false;
  1550. }
  1551.  
  1552. pascal Boolean dumbfilter(DialogPtr dlog, EventRecord *evt, int *itemhit)
  1553. {
  1554.     int c;
  1555.     switch(evt->what) {
  1556.     case keyDown:
  1557.     case autoKey:
  1558.         c = evt->message & charCodeMask;
  1559.         if ( c == 8 || ( c >= 28 && c <= 31 ) || ( c > 31 ) )
  1560.             break;
  1561.         return true;        /* don't process <returns> etc. */
  1562.     }
  1563.     return false;
  1564. }
  1565.  
  1566. void
  1567. MyNoteAlert(unsigned char stringnum)
  1568. {
  1569. register unsigned char *strptr;
  1570. char    **messages;
  1571.  
  1572.     messages = (char **) Get1Resource('STR#',STATUSSTRINGS);
  1573.     strptr = *messages;
  1574.     strptr++;
  1575.     if (stringnum > *strptr++ )        /* check if string is out of range */
  1576.         return;
  1577.     while (--stringnum > 0)            /* find string in list */
  1578.         strptr += *strptr + 1;
  1579.     HLock((Handle) messages);        /* lock down the Handle */
  1580.     ParamText(strptr,"\p","\p","\p");    /* set the text in the dialog */
  1581.     HUnlock((Handle) messages);
  1582.     ResetAlrtStage();
  1583.     NoteAlert(ERRALERT, nil);
  1584.     ReleaseResource((Handle) messages);
  1585. }
  1586.  
  1587. void initconfigs(struct cdevstore *p) {
  1588. int        i;
  1589.  
  1590.     p->prefcnfg.lcpconf = p->deflcp;
  1591.     p->prefcnfg.ipcpconf = p->defipcp;
  1592.     p->prefcnfg.pap_retries = 10;
  1593.     p->prefcnfg.pap_timeout = 3;
  1594.     p->prefcnfg.baudrate = 9600;    /* use 9600 as default for baudrate */
  1595.     p->prefcnfg.flowctl_on = 0;        /* don't use CTS flow control */
  1596.     p->prefcnfg.config_name[0] = 0;
  1597.     p->prefcnfg.defaultid[0] = 0;    /* init strings */
  1598.     p->prefcnfg.defaultpw[0] = 0;
  1599.     p->prefcnfg.modeminit[0] = 0;
  1600.     p->prefcnfg.phonenum[0] = 0;
  1601.     p->prefcnfg.connecttimeout = 90;    /* initial connect timeout */
  1602.     p->prefcnfg.waittimeout = 40; /* initial wait timeout */
  1603.     for (i=0 ; i < NUMCOMMANDS; i++) {
  1604.         p->prefcnfg.commands[i].sendout = true; /* make all output */
  1605.         p->prefcnfg.commands[i].addreturn = false; /* no returns */
  1606.         p->prefcnfg.commands[i].scriptstr[0] = 0;
  1607.     }
  1608. }
  1609.  
  1610. void AppendStr(unsigned char *dst, unsigned char *src)
  1611. {
  1612. unsigned char        dl,sl;
  1613.  
  1614.     dl = *dst;
  1615.     sl = *src++;
  1616.     *dst++ += sl;
  1617.     dst    += dl;
  1618.     BlockMove(src, dst, (unsigned long) sl);
  1619. }
  1620.  
  1621.